package com.linjiang.server.aspect;

import com.linjiang.server.annotation.GlobalTransactional;
import com.linjiang.server.transactional.BatchTransaction;
import com.linjiang.server.transactional.GlobalTransactionManager;
import com.linjiang.server.transactional.TransactionStatus;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 分布式事务注解@GlobalTransactional切面逻辑
 */
@Aspect
@Component
public class GlobalTransactionAspect implements Ordered {
    @Around("@annotation(com.linjiang.server.annotation.GlobalTransactional)")
    public void invoke(ProceedingJoinPoint point) {
        System.out.println("执行分布式事务注解@GlobalTransactional切面逻辑");
        // 打印出这个注解所对应的方法
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        //解析方法上的全局事务注解
        GlobalTransactional globalTransactionalAnnotation = method.getAnnotation(GlobalTransactional.class);
        //全局事务组id
        String groupId = "";
        if (globalTransactionalAnnotation.isStart()) {
            //创建全局事务并返回全局事务组id
            groupId = GlobalTransactionManager.createGlobalTransactionGroup();
        } else {
            //获取当前线程全局事务组id
            groupId = GlobalTransactionManager.getCurrentGroupId();
        }

        //创建分支事务
        BatchTransaction batchTransaction = GlobalTransactionManager.createBatchTransaction(groupId);

        try {
            // spring会开启mysql本地事务
            point.proceed();
            //注册分支事务 提交状态
            GlobalTransactionManager.registerBatchTransaction(batchTransaction, globalTransactionalAnnotation.isEnd(), TransactionStatus.commit);
        }catch (Exception e) {
            //本地事务执行失败
            //注册分支事务 回滚状态
            //本地事务执行失败
            //注册分支事务 回滚状态
            GlobalTransactionManager.registerBatchTransaction(batchTransaction, globalTransactionalAnnotation.isEnd(), TransactionStatus.rollback);
            e.printStackTrace();
        } catch (Throwable throwable) {
            //本地事务执行失败
            //注册分支事务 回滚状态
            GlobalTransactionManager.registerBatchTransaction(batchTransaction, globalTransactionalAnnotation.isEnd(), TransactionStatus.rollback);
            throwable.printStackTrace();
        }
    }

    /**
     * 切面优先级
     * @return
     */
    @Override
    public int getOrder() {
        return 10000;
    }
}
